package com.kingyea.mobilepolice.organization.controller;

import com.kingyea.mobilepolice.organization.bean.AuthVo;
import com.kingyea.mobilepolice.organization.bean.Organization;
import com.kingyea.mobilepolice.organization.bean.OrganizationCondition;
import com.kingyea.mobilepolice.organization.bean.OrganizationVo;
import com.kingyea.mobilepolice.organization.service.OrganizationService;
import com.kingyea.mobilepolice.security.SecurityUtils;
import com.kingyea.mobilepolice.system.Result;
import com.kingyea.mobilepolice.system.StateCode;
import com.kingyea.mobilepolice.user.bean.User;
import com.kingyea.mobilepolice.user.bean.UserCondition;
import com.kingyea.mobilepolice.user.service.UserService;
import com.kingyea.mobilepolice.userorg.bean.UserOrgCondition;
import com.kingyea.mobilepolice.userrole.bean.UserRole;
import com.kingyea.mobilepolice.userrole.bean.UserRoleCondition;
import com.kingyea.mobilepolice.userrole.service.UserRoleService;
import com.kingyea.mobilepolice.util.BasePage;
import com.kingyea.mobilepolice.util.ExceptionConditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description Organization 控制层
 * @date Created in 2018-03-30 15:26:52
 */
@CrossOrigin
@RequestMapping(value = "/organization")
@RestController
public class OrganizationController {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrganizationController.class);

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;
//    @Autowired
//    private AuthorizeServiceClient authorizeServiceClient;

    /**
     * @Description: 树结构部门数据全部返回，通用接口用于显示，以顶级部门为首，没有顶级部门就没数据
     * @Param: [condition]
     * @return: com.kingyea.mobilepolice.system.Result<java.util.List                                                                                                                                                                                                                                                               <                                                                                                                                                                                                                                                               com.kingyea.mobilepolice.organization.bean.OrganizationVo>>
     * @Author: cxc
     * @Date: 2018.04.09 14:01
     */
    @PostMapping("/tree")
    public Result<List<OrganizationVo>> tree(@RequestBody OrganizationCondition condition) {
        return new Result<>(organizationService.searchTree(condition));
    }

    @PostMapping("/pcTree")
    public Result<List<OrganizationVo>> pcTree(@RequestBody OrganizationCondition condition) {
        return new Result<>(organizationService.searchPctree(condition));
    }

    /**
     * @Description: 搜索用户id用户管理的树结构部门数据全部返回
     * @Param: [condition]
     * @return: com.kingyea.mobilepolice.system.Result<java.util.List                                                                                                                                                                                                                                                               <                                                                                                                                                                                                                                                               com.kingyea.mobilepolice.organization.bean.OrganizationVo>>
     * @Author: cxc
     * @Date: 2018.04.09 14:01
     */
    @PostMapping("/searchByUserId")
    public Result<List<OrganizationVo>> searchByUserId(@RequestBody OrganizationCondition condition) {
        return new Result<>(organizationService.searchAllOrgOfUser(condition.getUserId()));
    }

    /**
     * @Description: 当前用户管理的树结构部门数据全部返回
     * @Param: [condition]
     * @return: com.kingyea.mobilepolice.system.Result<java.util.List                                                                                                                               <                                                                                                                               com.kingyea.mobilepolice.organization.bean.OrganizationVo>>
     * @Author: cxc
     * @Date: 2018.04.09 14:01
     */
    @PostMapping("/mytree")
    public Result<List<OrganizationVo>> myOrgTree() {
        if (SecurityUtils.isAdmin()) {
            OrganizationCondition condition = new OrganizationCondition();
            condition.setPageAble(false);
            return new Result<>(organizationService.searchTree(condition));
        }
        return new Result<>(organizationService.searchAllOrgOfUser(SecurityUtils.getCurrentUser().getUserId()));
    }

    @PostMapping("/myOrgs")
    public Object myOrg(@RequestBody UserOrgCondition condition) throws Exception {
        OrganizationCondition orgCondition = new OrganizationCondition();
        BeanUtils.copyProperties(condition, orgCondition);
        List<Organization> list = organizationService.search(condition);
        if (SecurityUtils.isAdmin()) {
            list = organizationService.search(orgCondition);
            condition.setTotal(orgCondition.getTotal());
        }
        //设置父级部门名称 parentOrgName
        List<String> parentOrgSerialNoList = list.stream().map(Organization::getParentSerialNo).distinct().collect(Collectors.toList());
        OrganizationCondition parentCondition = new OrganizationCondition();
        parentCondition.setPageAble(false);
        parentCondition.setOrgIds(parentOrgSerialNoList);
        List<Organization> parentOrgList = organizationService.search(parentCondition);
        List<OrganizationVo> voList = list.stream().map(bean -> {
            OrganizationVo vo = new OrganizationVo();
            BeanUtils.copyProperties(bean, vo);
            parentOrgList.stream().filter(p -> p.getOrgSerialNo().equals(vo.getParentSerialNo())).findAny().ifPresent(p -> vo.setParentOrganizationName(p.getName()));
            return vo;
        }).collect(Collectors.toList());
        BasePage<OrganizationVo> voCondition = new BasePage<>();
        BeanUtils.copyProperties(condition, voCondition);
        voCondition.setList(voList);
        voCondition.setTotal(condition.getTotal());

        return voCondition;
    }

    /**
     * @Description: 查询全部，条件查询接口
     * @Param: [condition]
     * @return: java.util.List<com.kingyea.mobilepolice.organization.bean.Organization>
     * @Author: cxc
     * @Date: 2018.04.09 14:28
     */
    @PostMapping("/search")
    public Object list(@RequestBody OrganizationCondition condition) throws Exception {
        List<Organization> organizationList = organizationService.search(condition);
        Set<String> parentIdSet = organizationList.stream().map(Organization::getParentSerialNo).collect(Collectors.toSet());
        OrganizationCondition parentCondition = new OrganizationCondition();
        parentCondition.setPageSize(condition.getPageSize());
        parentCondition.setOrgIds(new ArrayList<>(parentIdSet));
        List<Organization> parentOrgList = organizationService.search(parentCondition);
        List<OrganizationVo> voList = organizationList.stream().map(o -> {
            OrganizationVo vo = new OrganizationVo();
            BeanUtils.copyProperties(o, vo);
            Optional<Organization> first = parentOrgList.stream().filter(p -> o.getParentSerialNo().equals(p.getOrgSerialNo())).findFirst();
            if (first.isPresent()) {
                vo.setParentOrganizationName(first.get().getName());
            }
            return vo;
        }).collect(Collectors.toList());
        BasePage<OrganizationVo> baseCondition = new BasePage<OrganizationVo>();
        BeanUtils.copyProperties(condition, baseCondition);
        baseCondition.setList(voList);
        baseCondition.setTotal(condition.getTotal());
        return baseCondition;
    }

    /**
     * 通过ID查找对象
     *
     * @param orgId
     * @return
     */
    @PreAuthorize("hasAuthority('detail-organization')")
    @RequestMapping(value = "/{orgId}", method = RequestMethod.GET)
    public Object detail(@PathVariable Integer orgId) throws Exception {
        return organizationService.getById(orgId);
    }

    /**
     * @Description: vo扩展显示数据
     * @Param: [condition]
     * @return: java.lang.Object
     * @Author: cxc
     * @Date: 2018.04.09 20:58
     */
    @RequestMapping(value = "/queryByCondition", method = RequestMethod.POST)
    public Object queryByCondition(@RequestBody OrganizationCondition condition) throws Exception {
        List<Organization> organizationList = organizationService.queryByCondition(condition);
        Set<String> parentIdSet = organizationList.stream().map(Organization::getParentSerialNo).collect(Collectors.toSet());
        OrganizationCondition parentCondition = new OrganizationCondition();
        parentCondition.setPageSize(condition.getPageSize());
        parentCondition.setOrgIds(new ArrayList<>(parentIdSet));
        List<Organization> parentOrgList = organizationService.search(parentCondition);
        List<OrganizationVo> voList = organizationList.stream().map(o -> {
            OrganizationVo vo = new OrganizationVo();
            BeanUtils.copyProperties(o, vo);
            Optional<Organization> first = parentOrgList.stream().filter(p -> o.getParentSerialNo().equals(p.getOrgSerialNo())).findFirst();
            if (first.isPresent()) {
                vo.setParentOrganizationName(first.get().getName());
            }
            return vo;
        }).collect(Collectors.toList());
        BasePage<OrganizationVo> baseCondition = new BasePage<OrganizationVo>();
        BeanUtils.copyProperties(condition, baseCondition);
        baseCondition.setList(voList);
        return baseCondition;
    }

    /**
     * @Description: 添加部门
     * @Param: [organization]
     * @return: java.lang.Object
     * @Author: cxc
     * @Date: 2018.04.13 10:31
     */
    @PreAuthorize("hasAuthority('create-organization')")
    @PostMapping("/save")
    public Object create(@RequestBody Organization organization) throws Exception {
        ExceptionConditions.checkNotNull(organization, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(organization.getType(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getIcode(), StateCode.NO_ARGUMENT_ERROR);
//        ExceptionConditions.checkStringNotEmpty(organization.getCode(), StateCode.NO_ARGUMENT_ERROR);
        return organizationService.save(organization);
    }

    /**
     * @Description: 修改部门
     * @Param: [organization]
     * @return: java.lang.Object
     * @Author: cxc
     * @Date: 2018.04.13 10:31
     */
    @PreAuthorize("hasAuthority('update-organization')")
    @PostMapping("/update")
    public Object update(@RequestBody Organization organization) throws Exception {
        ExceptionConditions.checkNotNull(organization, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getOrgSerialNo(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(organization.getType(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getIcode(), StateCode.NO_ARGUMENT_ERROR);
//        ExceptionConditions.checkStringNotEmpty(organization.getCode(), StateCode.NO_ARGUMENT_ERROR);
        return organizationService.update(organization);
    }

    /**
     * 删除
     *
     * @param orgId
     * @return
     */
    @PreAuthorize("hasAuthority('delete-organization')")
    @PostMapping("/delete/{orgId}")
    public Object delete(@PathVariable Integer orgId) throws Exception {
        return organizationService.deleteById(orgId) == 1;
    }

    /**
     * 父级部门
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/parentDeptList", method = RequestMethod.POST)
    public Object parentDeptList() throws Exception {
        return organizationService.parentDeptList();

    }

    /**
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/authTree", method = RequestMethod.POST)
    public Object authTree(@RequestBody Map<String, Object> map) throws Exception {
        List<User> list = userService.list(map);
        List<Organization> list2 = organizationService.list(map);
        ArrayList<AuthVo> arrayList = new ArrayList<AuthVo>();
        for (User user : list) {
            AuthVo authVo = new AuthVo();
            authVo.setUser(user);
            authVo.setOrgId(user.getId());
            authVo.setName(user.getLoginId());
            arrayList.add(authVo);

        }
        for (Organization organization : list2) {
            AuthVo authVo = new AuthVo();
            authVo.setOrganization(organization);
            authVo.setOrgId(organization.getOrgId());
            authVo.setOrgSerialNo(organization.getOrgSerialNo());
            authVo.setName(organization.getName());
            arrayList.add(authVo);
        }
        return arrayList;

    }


    /**
     * 根据部门标识查询该部门下的子部门
     *
     * @param map
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/deptTree", method = RequestMethod.POST)
    public Object deptTree(@RequestBody Map<String, Object> map) throws Exception {
        List<Organization> list = organizationService.list(map);
        return list;
    }


    /**
     * @Description: 更新用户管理的部门
     * @Param: [orgIdStrList]
     * @return: java.lang.Object
     * @Author: cxc
     * @Date: 2018.04.09 15:53
     */
    @PreAuthorize("hasAuthority('allot-organization')")
    @PostMapping("/updateOrgsForUser")
    public Object updateOrgForUser(@RequestBody OrganizationCondition condition) {
        ExceptionConditions.checkStringNotEmpty(condition.getUserSerialNo(), StateCode.NO_ARGUMENT_ERROR);
        if (condition.getUserOrgList() == null || condition.getUserOrgList().size() == 0) {
            return organizationService.delAllOrgByUserSerialNo(condition.getUserSerialNo());
        }
        return organizationService.addAllOrgOfUser(condition.getUserSerialNo(), condition.getUserOrgList());
    }

    /**
     * 封装部门授权  列表
     *
     * @param condition
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/authDeptList", method = RequestMethod.POST)
    public Object authDept(@RequestBody OrganizationCondition condition) throws Exception {
        List<Organization> orgList = organizationService.queryByCondition(condition);//部门
        condition.setList(orgList);
        return condition;

    }

    @RequestMapping(value = "/getBySerialNo", method = RequestMethod.POST)
    public Object getBySerialNo(@RequestParam(value = "serialNo") String serialNo) throws Exception {
        return organizationService.getBySerialNo(serialNo);

    }

    @RequestMapping(value = "/getByUserId", method = RequestMethod.POST)
    public Object getByUserId(@RequestBody OrganizationCondition condition) throws Exception {
        ExceptionConditions.checkStringNotEmpty(condition.getUserId(), StateCode.NO_ARGUMENT_ERROR);
        User user = userService.getByUserId(condition.getUserId());
        ExceptionConditions.checkNotNull(user, StateCode.SERVER_DATA_MISSING_ERROR);
        return organizationService.getBySerialNo(user.getOrgSerialNo());

    }

    @RequestMapping(value = "/getOrgNameByRole")
    public Object getOrgNameByRole() throws Exception {
        List list = new ArrayList();
        UserRoleCondition condition = new UserRoleCondition();
        condition.setRoleId(2);
        List<UserRole> userRole = userRoleService.search(condition); // 市场管理员角色对应的用户
        List<String> userIdList = userRole.stream().map(UserRole::getUserId).distinct().collect(Collectors.toList()); //获取市场管理员的所有userid
        UserCondition userCondition = new UserCondition();
        userCondition.setUserIdList(userIdList);
        List<User> userList = userService.search(userCondition); //获取市场管理员的所有user
        for (User user : userList) {
            Organization secOrg = getSecOrg(user.getOrgSerialNo());
            if (secOrg == null) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("orgAndUserName", secOrg.getName() + ":" + user.getName());
            map.put("orgName", secOrg.getName());
            map.put("userId", user.getUserId());
            map.put("userName", user.getName());
            map.put("lxdh", user.getMobile());
            list.add(map);
        }
        return list;
    }

    Organization getSecOrg(String orgSerialNo) throws Exception {
        Organization org = organizationService.getBySerialNo(orgSerialNo);
        if (org == null) {
            return org;
        }
        if (org.getParentSerialNo().equals("0")) {
            return org;
        }
        return getSecOrg(org.getParentSerialNo());

    }


    /**
     * 获取自己所在的部门信息和返回最高级别部门
     * @return
     */
    @PostMapping("/selectByMyOrg")
    public Result myOrg() {
        return organizationService.selectByMyDept();
    }

    /**
     * 获取自己所在部门的下级部门和人员
     * @return
     */
    @PostMapping("/selectByMyDept/{orgId}")
    public Result myDepts(@PathVariable String orgId) {
        return new Result(organizationService.searchMyDept(orgId));
    }

    /**
     * 获取自己的上级部门和自己的部门（部门名片使用）
     * @param orgId
     * @return
     */
    @PostMapping( "/getMyDept/{orgId}")
    public Result getDeptDetail(@PathVariable String orgId){
        return organizationService.searchCard(orgId);
    }

    /**
     * 获取个人名片
     * @param userId
     * @return
     */
    @PostMapping( "/getPersionCard/{userId}")
    public Result searchPersionCard(@PathVariable String userId){
        return organizationService.searchPersionCard(userId);
    }

    /**
     * 通过用户名、部门名模糊查询
     * @param organization
     * @return
     */
    @PostMapping("/searchByName")
    public Result searchByName(@RequestBody Organization organization) {
        return organizationService.searchByName(organization);
    }
}
